﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Persistencia;
using GestorDeFlotasModelo.Entities;
using Persistencia.Interfaces;
using System.Data.SqlClient;
namespace GestorDeFlotasModelo.Factorias
{
    public class FactoriaViaje : Factoria , IIdentityFactory
    {
        private FactoriaViaje(TransaccionBase tran)
            : base(tran) 
        {
        }
        

        public override string NombreTabla
        {
            get { return " NUESTRA_RUBIA_ES_MEJOR.Viaje "; }
        }

        protected override IPersistibleModelo NuevoPersistible(HashTableNCSensitive htsNc)
        {
            return new Viaje();
        }

        protected override string Id(HashTableNCSensitive hts)
        {
            return hts["Viaje_Id"].ToString();
        }


        protected override HashTableNCSensitive ParametrosClave()
        {
            HashTableNCSensitive parameters = new HashTableNCSensitive();
            parameters.Add("Viaje_Id", null);
            return parameters;
        }

        protected override HashTableNCSensitive ParametrosNoClave()
        {
            HashTableNCSensitive parameters = new HashTableNCSensitive();
            parameters.Add("Viaje_Chofer", null);
            parameters.Add("Viaje_Auto", null);
            parameters.Add("Viaje_Turno", null);
            parameters.Add("Viaje_Cliente", null);
            parameters.Add("Viaje_Reloj", null);
            parameters.Add("Viaje_Fecha", null);
            parameters.Add("Viaje_Cant_Fichas", null);
            parameters.Add("Viaje_Rendicion", null);
            parameters.Add("Viaje_Factura", null);
            return parameters;
        }


        protected override Predicate<IPersistibleModelo> FiltroXId(string id)
        {
            return delegate(IPersistibleModelo iPer)
            {
                return ((Viaje)iPer).Id == long.Parse(id);
            };
        }

        

        public List<Viaje> SelectInconsistentes()
        {

            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT * FROM "+this.NombreTabla+" WHERE Viaje_Consistente=0";
            comm.CommandText = consulta;
            return base.Select<Viaje>(comm, delegate(IPersistibleModelo iPer)
            {
                return !((Viaje)iPer).Consistente && !iPer.Persistible.Eliminado;
            });
        }

        public List<Viaje> SelectPorClienteYFechas(Cliente cliente, DateTime fechaInicio, DateTime fechaFin)
        {
            SqlCommand comm = new SqlCommand();
            comm.CommandText = "SELECT * FROM " + this.NombreTabla + " WHERE Viaje_Cliente = @Cliente_Id AND (Viaje_Fecha BETWEEN @FechaInicio AND @FechaFin) AND Viaje_Consistente = 1";
            comm.Parameters.AddWithValue("@Cliente_Id", cliente.Id);
            comm.Parameters.AddWithValue("@FechaInicio", fechaInicio);
            comm.Parameters.AddWithValue("@FechaFin", fechaFin);

            List<Viaje> viajes = base.Select<Viaje>(comm, delegate(IPersistibleModelo iPer) { return ((Viaje)iPer).Cliente.Id == cliente.Id; });

            if (viajes.Count > 0)
                return viajes;
            else
                return new List<Viaje>();
        }

        public double SelectImporteTotalFactura(Cliente cliente, DateTime fechaInicio, DateTime fechaFin)
        {
            
            SqlCommand comm = new SqlCommand();
            comm.CommandText = "SELECT SUM(t.Turno_Valor_Bandera + t.Turno_Valor_Ficha * v.Viaje_Cant_Fichas) as Monto from NUESTRA_RUBIA_ES_MEJOR.Viaje v INNER JOIN NUESTRA_RUBIA_ES_MEJOR.Turno t ON t.Turno_Id = v.Viaje_Turno WHERE v.Viaje_Cliente = @Cliente_Id AND (v.Viaje_Fecha BETWEEN @FechaInicio AND @FechaFin) AND v.Viaje_Consistente=1 GROUP BY v.Viaje_Cliente";
            comm.Parameters.AddWithValue("@Cliente_Id", cliente.Id);
            comm.Parameters.AddWithValue("@FechaInicio", fechaInicio);
            comm.Parameters.AddWithValue("@FechaFin", fechaFin);

            List<HashTableNCSensitive> result = Transaccion.EjecutarComando(comm, 0);
            double importe = 0;


            if (result.Count > 0 && double.TryParse(result[0]["Monto"].ToString(), out importe))
                return importe;
            else
                return 0;
        }

        public List<Viaje> SelectViajesConInconsistencias(int pagina, int registrosXPagina)
        {
            SqlCommand comm = new SqlCommand();
            int cantidad = registrosXPagina * pagina;
            string consulta = "SELECT TOP "+cantidad+" * FROM "+this.NombreTabla+" WHERE V1.Viaje_Consistente=1 AND  Exists( Select * FROM NUESTRA_RUBIA_ES_MEJOR.Viaje V2	WHERE V1.Viaje_Fecha=V2.Viaje_Fecha and v1.Viaje_Cliente!= V2.Viaje_Cliente AND (V1.Viaje_Auto=V2.Viaje_Auto OR  V1.Viaje_Chofer=V2.Viaje_Chofer) AND V2.Viaje_Consistente=0) ORDER BY V1.Viaje_Fecha DESC";
            comm.CommandText=consulta;
            List<Viaje> todos = base.SelectTodos<Viaje>();
            base.todaLaBaseCargada = true;
            List<Viaje> viajes= base.Select<Viaje>(comm,delegate(IPersistibleModelo iPer)
            {
                Viaje v1=((Viaje)iPer);
                if(!v1.Consistente)
                    return false;

                return todos.Exists(delegate(Viaje v2)
                {
                    return v1.Fecha.Equals(v2.Fecha) && v1.Cliente.Id != v2.Cliente.Id && (v1.Auto.Id == v2.Auto.Id || v1.Chofer.Id == v2.Chofer.Id);
                });
            },cantidad);

            viajes.Sort(delegate(Viaje v1, Viaje v2)
            {
                return v1.Fecha.CompareTo(v2.Fecha);
            });

            return (List<Viaje>)viajes.Skip<Viaje>((pagina - 1) * registrosXPagina).Take(registrosXPagina);
        }

        public List<Viaje> SelectInconsistentesDe(Viaje viaje)
        {
            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT * FROM " + this.NombreTabla + " WHERE Viaje_Consistente=0 AND Viaje_Fecha=@Fecha AND (Viaje_Auto=@Auto OR Viaje_Chofer=@Chofer) AND Viaje_Id != @Id";
            comm.CommandText = consulta;
            comm.Parameters.AddWithValue("@Fecha", viaje.Fecha);
            comm.Parameters.AddWithValue("@Chofer", viaje.Chofer.Id);
            comm.Parameters.AddWithValue("@Auto", viaje.Auto.Id);
            comm.Parameters.AddWithValue("@Id", viaje.Id);
           List<Viaje> viajesInconsistentes= base.Select<Viaje>(comm, delegate(IPersistibleModelo iPer)
            {
                Viaje v = (Viaje)iPer;
                return !v.Consistente && v.Fecha.Equals(viaje.Fecha) && v.Id != viaje.Id && (v.Auto.Id == viaje.Auto.Id || v.Chofer.Id == viaje.Chofer.Id)&& !iPer.Persistible.Eliminado;
            });
           return viajesInconsistentes;
        }

        public List<Viaje> SelectParaRendicion(Int64 chofer, Int64 turno, DateTime fecha)
        {
            SqlCommand comm = new SqlCommand();
            comm.CommandText = "SELECT * FROM " + this.NombreTabla + " WHERE Viaje_Chofer = @Chofer_id AND Viaje_Turno = @Turno_id AND DATEADD(D, 0, DATEDIFF(D,0,Viaje_Fecha)) = @Fecha AND Viaje_Consistente=1";
            comm.Parameters.AddWithValue("@Chofer_id", chofer);
            comm.Parameters.AddWithValue("@Turno_id", turno);
            comm.Parameters.AddWithValue("@Fecha", fecha.Date);

            List<Viaje> viajes = base.Select<Viaje>(comm, delegate(IPersistibleModelo iPer) { return ((Viaje)iPer).Chofer.Id == chofer
                                                                                                && ((Viaje)iPer).Fecha.Date == fecha.Date
                                                                                                && ((Viaje)iPer).Turno.Id == turno; });
            if (viajes.Count > 0)
                return viajes;
            else
                return new List<Viaje>();
        }

        public List<Viaje> SelectRepetidos(Chofer chofer, Auto auto, DateTime fecha)
        {
            SqlCommand comm = new SqlCommand();
            string consulta = "SELECT TOP 1 * FROM " + this.NombreTabla + "WHERE Viaje_Fecha=@Fecha AND (Viaje_Chofer=@Chofer OR Viaje_Auto=@Auto) AND Viaje_Consistente=1";
            comm.CommandText = consulta;
            comm.Parameters.AddWithValue("@Fecha", fecha);
            comm.Parameters.AddWithValue("@Chofer", chofer.Id);
            comm.Parameters.AddWithValue("@Auto", auto.Id);
           
            return base.Select<Viaje>(comm, delegate(IPersistibleModelo iPer)
            {
                return ((Viaje)iPer).Fecha.Equals(fecha) && (((Viaje)iPer).Auto.Id == auto.Id || ((Viaje)iPer).Chofer.Id == chofer.Id) && ((Viaje)iPer).Consistente;
            });

        }

        public Viaje Nuevo(Auto auto ,Turno turno, Chofer chofer, Cliente cli, int cantidadFichas, DateTime fecha)
        {
            Viaje v = new Viaje();
            v.Auto = auto;
            v.Turno = turno;
            v.Chofer = chofer;
            v.Cliente = cli;
            v.Fecha = fecha;
            v.CantFichas = cantidadFichas;
            v.Reloj = auto.Reloj;
            v.Consistente = true;
            base.Agregar(v);
            return v;
        }
    }
}
